package com.gao.api.gate.quick.tt;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoop;
import io.netty.channel.pool.ChannelHealthChecker;
import io.netty.channel.pool.ChannelPoolHandler;
import io.netty.channel.pool.FixedChannelPool;
import io.netty.util.AttributeKey;

/**
 * <p></p>
 *
 * @author gaoshuangwen
 * @since 2022/02/12 14:50
 */
public class TimeToLiveChannelPool extends FixedChannelPool implements ChannelPool {

    private static final AttributeKey<TimeToLiveChannel> TTL_CHANNEL =
            AttributeKey.valueOf("TimeToLiveChannel");

    private static final ChannelHealthChecker ACTIVE = channel -> {
        EventLoop loop = channel.eventLoop();
        TimeToLiveChannel timeToLiveChannel = channel.attr(TTL_CHANNEL).get();
        return channel.isActive() && timeToLiveChannel.isEvict()? loop.newSucceededFuture(Boolean.TRUE) : loop.newSucceededFuture(Boolean.FALSE);
    };
    public TimeToLiveChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections) {
        super(bootstrap, handler, maxConnections);
    }

    public TimeToLiveChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections, int maxPendingAcquires) {
        super(bootstrap, handler, maxConnections, maxPendingAcquires);
    }

    public TimeToLiveChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires) {
        super(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires);
    }

    public TimeToLiveChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires, boolean releaseHealthCheck) {
        super(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, releaseHealthCheck);
    }

    public TimeToLiveChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires, boolean releaseHealthCheck, boolean lastRecentUsed) {
        super(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, releaseHealthCheck, lastRecentUsed);
    }



    @Override
    public void evict() {


    }

    public static class TimeToLiveChannelPoolHandler implements ChannelPoolHandler {

        @Override
        public void channelReleased(Channel ch) throws Exception {
            ch.attr(TTL_CHANNEL).get().updated(System.currentTimeMillis());
        }

        @Override
        public void channelAcquired(Channel ch) throws Exception {
            ch.attr(TTL_CHANNEL).get().updated(System.currentTimeMillis());
        }

        @Override
        public void channelCreated(Channel ch) throws Exception {
            TimeToLiveChannel reusableChannel = new TimeToLiveChannel(ch, null, null);
            ch.attr(TTL_CHANNEL).set(reusableChannel);
        }

    }
}
